<!DOCTYPE html>
<html lang="en">
	<head>
		<meta charset="utf-8">
    <title>Cindy JS</title>
    <script type="text/javascript" src="../../build/js/Cindy.js"></script>
    <script type="text/javascript" src="../../build/js/CindyGL.js"></script>
    <link rel="stylesheet" href="../../css/cindy.css">
  </head>
    
	<body style="font-family:Arial;">
    
    <h1>CindyJS: Generation of Limit Sets of Kleinian Groups Using a Feedback Loop Approach</h1>
    
    Press SPACE to reset everything. The red and the blue point determine the complex parameters ta, tb, which will be pluged into Grandma's recipe from Indra's Pearls: The Vision of Felix Klein, David Mumford, ‎Caroline Series, ‎David Wright.
  
               
    <script id="csinit" type="text/x-cindyscript">
      use("CindyGL");
      
      forall(["a", "b", "A", "B"],
        createimage(#, 500, 500);
        colorplot(#, 0); //initialize as black
      );
    </script>
    
    <script id="csmove" type="text/x-cindyscript">
      ta = .5*complex(TA)+2;
      tb = .5*complex(TB)+2;
      
      //Grandma's recipe from Indra's Pearls: The Vision of Felix Klein, David Mumford, ‎Caroline Series, ‎David Wright 
      tab = ta*tb/2-i*sqrt(-((ta*tb/2)^2-ta^2-tb^2));
      z0 = ((tab-2)*tb)/(tb*tab-2*ta+2*i*tab);
      a = [
        [ta/2,(ta*tab-2*tb+4*i)/((2*tab+4)*z0)],
        [(ta*tab-2*tb-4*i)*z0/(2*tab-4),ta/2]
      ];
      b = [
        [(tb-2*i)/2,tb/2],
        [tb/2,(tb+2*i)/2]
      ];
      
      b = a*b; //replace b by a*b for better results
      
      A = inverse(a);
      B = inverse(b);
  </script>
      
  <script id="cskeydown" type="text/x-cindyscript">
      print("pressed key" + keycode());
      if(keycode()==32, 
        forall(["a", "b", "A", "B"],
          colorplot(#, 0);
        );
      ); //space -> black
 </script>
    
    <script id="csdraw" type="text/x-cindyscript">          
      T(a) := ( //maps [0,1] to [0, oo)
        res = a/(1-a);
        res*res);

      Tinv(a) := ( //maps [0,oo) to [0, 1]
        a = re(sqrt(a));
        a/(1+a);
      );
      
          
      forall([
        ["a", a, ["a", "b", "B"]],  //i,e. image "a" is derivated by applying the inverse mobius transformation of a to the three images "a", "b", "B"
        ["b", b, ["a", "b", "A"]],
        ["A", A, ["b", "A", "B"]],
        ["B", B, ["a", "A", "B"]]
      ], trafo,
       colorplot(trafo_1,
          x = trafo_2*[complex(#), 1];
          origin = x_1/x_2;             //moebius trafo_2 applied to complex(#)
          f = 1/re(x_2*conjugate(x_2)); //derivation of the moebius transformation at complex(#)
          Tinv(f*f*(
              T(imagergb(trafo_3_1, origin).r)
            + T(imagergb(trafo_3_2, origin).r)
            + T(imagergb(trafo_3_3, origin).r)
          ) + .000001*exp(-(#*#)))
        );
      );
      
      colorplot(
        s0 = imagergb("a", #).r;
        s1 = imagergb("A", #).r;
        s2 = imagergb("b", #).r;
        s3 = imagergb("B", #).r;
        sum = (s0+s1+s2+s3);
        gray(sum)+
        s0*hue(1/8)+s1*hue(3/8)+s2*hue(5/8)+s3*hue(7/8)
      );
      
      drawtext(TA+(.01,.01), ta, color->[1,0,0]);
      drawtext(TB+(.01,.01), tb, color->[0,0,1]);
    </script>

    <div  id="CSCanvas" style="position:relative; top:10px;"></div>
    <script type="text/javascript">
        
        cdy = CindyJS({canvasname:"CSCanvas",
                    scripts: "cs*",
                    geometry: [{name:"TA", type:"Free", pos:[0.,0.],color:[1,0,0],pinned:false,size:6},
                              {name:"TB", type:"Free", pos:[0.,0.],color:[0,0,1],pinned:false,size:6}],
                    animation: {autoplay: true},
                    ports: [{
                      id: "CSCanvas",
                      width: 500,
                      height: 500,
                      transform: [ { visibleRect: [-1.5, -1.5, 1.5, 1.5] } ]
                    }]
                  });
    </script>              
	</body>
</html>
